package com.hcj.springcloud.BusinessDelegatePattern;

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;

/**
 * 商业委托模式-demo：
 * <pre>
 * Business Delegate Pattern用于解耦表示层和业务层。
 * 它基本上用于减少表示层代码中的业务层代码的通信或远程查找功能。
 * 在业务层，我们有以下实体。
 * 客户端 - 表示层代码可以是JSP，servlet或UI java代码。
 * 业务代表 - 客户实体提供对业务服务方法的访问的单一入口点类。
 * LookUp服务 - 查找服务对象负责获取相关业务实现并提供业务对象访问业务委托对象。
 * 商业服务 - 商业服务界面。具体类实现此业务服务以提供实际的业务实现逻辑。
 * </pre>
 * ---------------概览-----------------
 * <pre>
 * 我们将创建一个
 * Client，BusinessDelegate，BusinessService，LookUpService，JMSService和EJBService，
 * 代表Business Delegate模式的各种实体。
 * BusinessDelegatePatternDemo，我们的演示课，将使用BusinessDelegate和客户演示使用业务委托模式的。
 * </pre>
 *
 * @author huangchangjin
 * @date 2023/11/27 19:39
 */
@Slf4j
public class Demo {
    interface BusinessService {
        void doBusiness();
    }

    static class EJBService implements BusinessService {
        @Override
        public void doBusiness() {
            log.info("EJB业务");
        }
    }

    static class JMSService implements BusinessService {
        @Override
        public void doBusiness() {
            log.info("JMS业务");
        }
    }

    static class BusinessLookup {
        BusinessService doProcessing(String serviceType) {
            log.info("业务搜寻 serviceType = {}", serviceType);
            if (serviceType.equalsIgnoreCase("EJB")) {
                return new EJBService();
            } else {
                return new JMSService();
            }
        }
    }

    static class BusinessDelegate {
        protected BusinessLookup businessLookup = new BusinessLookup();
        protected BusinessService businessService;


        private String serviceType;

        public void setServiceType(String serviceType) {
            this.serviceType = serviceType;
        }

        private void lookupService() {
            businessService = businessLookup.doProcessing(serviceType);
        }

        public void doTask() {
            lookupService();
            log.info("doTask");
            businessService.doBusiness();
        }
    }

    static class Client {
        private BusinessDelegate delegate;

        public Client(BusinessDelegate delegate) {
            this.delegate = delegate;
        }

        public void doTask() {
            log.info("Client::doTask()  type = {}", delegate.serviceType);
            delegate.doTask();
        }
    }

    @Test
    void test_main() {
        BusinessDelegate businessDelegate = new BusinessDelegate();
        businessDelegate.setServiceType("EJB");
        Client client = new Client(businessDelegate);
        client.doTask();

        businessDelegate.setServiceType("JMS");
        client = new Client(businessDelegate);
        client.doTask();
    }
}
